Encryption and Decryption in zcash
Encryption
Note
code:get_note.rs
// Private utility function to get Note from C parameters
fn priv_get_note(
value: uint64_t,
) -> Result<sapling_crypto::primitives::Note<Bls12>, ()> {
let diversifier = sapling_crypto::primitives::Diversifier(unsafe { *diversifier });
let g_d = match diversifier.g_d::<Bls12>(&JUBJUB) {
Some(g_d) => g_d,
None => return Err(()),
};
let pk_d = match edwards::Point::<Bls12, Unknown>::read(&(unsafe { &*pk_d }).., &JUBJUB) { Ok(p) => p,
Err(_) => return Err(()),
};
let pk_d = match pk_d.as_prime_order(&JUBJUB) {
Some(pk_d) => pk_d,
None => return Err(()),
};
// Deserialize randomness
let r = match Fs::from_repr(read_fs(&(unsafe { &*r })..)) { Ok(r) => r,
Err(_) => return Err(()),
};
let note = sapling_crypto::primitives::Note {
value,
g_d,
pk_d,
r,
};
Ok(note)
}
code:enb.cpp
boost::optional<SaplingEncCiphertext> SaplingNoteEncryption::encrypt_to_recipient(
const uint256 &pk_d,
const SaplingEncPlaintext &message
)
{
if (already_encrypted_enc) {
throw std::logic_error("already encrypted to the recipient using this key");
}
uint256 dhsecret;
if (!librustzcash_sapling_ka_agree(pk_d.begin(), esk.begin(), dhsecret.begin())) {
return boost::none;
}
// Construct the symmetric key
KDF_Sapling(K, dhsecret, epk);
// The nonce is zero because we never reuse keys
SaplingEncCiphertext ciphertext;
crypto_aead_chacha20poly1305_ietf_encrypt(
ciphertext.begin(), NULL,
message.begin(), ZC_SAPLING_ENCPLAINTEXT_SIZE,
NULL, 0, // no "additional data"
NULL, cipher_nonce, K
);
already_encrypted_enc = true;
return ciphertext;
}
Decryption in snark